﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Modules.Entitys;
using Modules.Notify.Repositories;
using PmSoft;
using PmSoft.ApplicationContext;
using PmSoft.Exceptions;
using static Modules.Notify.NotifyConstants;

namespace Modules.Notify
{
    [UseDI(ServiceLifetime.Scoped)]
    public class SysNotifyService
    {
        private readonly SysNotifyRepository repository;
        private readonly IApplicationContext applicationContext;
        private readonly NotifyAttachmentService notifyAttachmentService;
        private readonly ILogger logger;

        public SysNotifyService(SysNotifyRepository repository, IApplicationContext applicationContext, NotifyAttachmentService notifyAttachmentService, ILogger<SysNotifyService> logger)
        {
            this.repository = repository;
            this.applicationContext = applicationContext;
            this.notifyAttachmentService = notifyAttachmentService;
            this.logger = logger;
        }

        public void CreateSysNotify(SysNotify entity, IEnumerable<string> attachmentIds)
        {
            entity.Creator = applicationContext.CurrentUser?.Name ?? string.Empty;
            entity.ReadedNum = 0;
            entity.CreateTime = DateTime.Now;
            if (attachmentIds.Count() == 0)
            {
                try
                {
                    applicationContext.Transaction.Begin();//开始事务
                    if (entity.IsTop && !string.IsNullOrEmpty(repository.TopNotify().Id))
                    {
                        var topNotify = repository.TopNotify();
                        topNotify.IsTop = false;
                        repository.Update(topNotify);
                    }
                    repository.Insert(entity);
                    applicationContext.Transaction.Complete();//完成事务
                }
                catch (Exception ex)
                {
                    applicationContext.Transaction.Abort();//回滚事务
                    logger.LogError(ex, $"创建系统通知失败");
                    throw new BusinessException("创建系统通知失败");
                }
                return;
            }
            try
            {
                applicationContext.Transaction.Begin();//开始事务
                if (entity.IsTop)
                {
                    var topNotify = repository.TopNotify();
                    if (!string.IsNullOrEmpty(topNotify.Id))
                    {
                        topNotify.IsTop = false;
                        repository.Update(topNotify);
                    }
                }
                repository.Insert(entity);
                foreach (var attachmentId in attachmentIds)
                {
                    notifyAttachmentService.CreateNotifyAttachment(new NotifyAttachment()
                    {
                        AttachmentId = attachmentId,
                        NotifyId = entity.Id,
                        AttachmentType = NotifyConstants.通知类型.系统通知,
                    });
                }
                applicationContext.Transaction.Complete();//完成事务
            }
            catch (Exception ex)
            {
                applicationContext.Transaction.Abort();//回滚事务
                logger.LogError(ex, $"创建系统通知失败");
                throw new BusinessException("创建系统通知失败");
            }
        }

        /// <summary>
        /// 获取最新的系统公告
        /// </summary>
        /// <returns></returns>
        public SysNotify New()
        {
            return repository.New();
        }

        /// <summary>
        /// 获取置顶公告
        /// </summary>
        /// <returns></returns>
        public SysNotify TopNotify()
        {
            return repository.TopNotify();
        }

        public void DeletSysNotifys(IEnumerable<string> ids)
        {
            foreach (string id in ids)
                DeleteSysNotify(id);
        }

        public void DeleteSysNotify(string id)
        {
            repository.DeleteByEntityId(id);
        }

        public SysNotify? GetSysNotify(string id)
        {
            return repository.Get(id);
        }

        public void UpdateSysNotify(SysNotify entity, IEnumerable<string> attachmentIds)
        {
            if (attachmentIds.Count() == 0)
            {
                try
                {
                    applicationContext.Transaction.Begin();//开始事务
                    if (entity.IsTop)
                    {
                        var topNotify = repository.TopNotify();
                        if (!string.IsNullOrEmpty(topNotify.Id) && topNotify.Id != entity.Id)
                        {
                            topNotify.IsTop = false;
                            repository.Update(topNotify);
                        }
                    }
                    repository.Update(entity);
                    applicationContext.Transaction.Complete();//完成事务
                }
                catch (Exception ex)
                {
                    applicationContext.Transaction.Abort();//回滚事务
                    logger.LogError(ex, $"更新系统通知失败");
                    throw new BusinessException("更新系统通知失败");
                }
                return;
            }
            try
            {
                applicationContext.Transaction.Begin();//开始事务
                entity.UpdateTime = DateTime.Now;
                if (entity.IsTop)
                {
                    var topNotify = repository.TopNotify();
                    if (!string.IsNullOrEmpty(topNotify.Id) && topNotify.Id != entity.Id)
                    {
                        topNotify.IsTop = false;
                        repository.Update(topNotify);
                    }
                }
                repository.Update(entity);
                //更新关联表
                List<NotifyAttachment> allLinks = notifyAttachmentService.GetNotifyAttachmentsByNotifyId(entity.Id, 通知类型.系统通知).ToList();
                List<NotifyAttachment> delLinks = allLinks.Where(i => !attachmentIds.Contains(i.AttachmentId)).ToList();
                List<string> addLinks = attachmentIds.Where(i => !allLinks.Exists(a => a.AttachmentId == i)).ToList();
                //删除旧关联
                notifyAttachmentService.DeletNotifyAttachments(delLinks.Select(i => i.Id).ToList());
                //创建新关联
                foreach (var attachmentId in addLinks)
                {
                    notifyAttachmentService.CreateNotifyAttachment(new NotifyAttachment()
                    {
                        AttachmentId = attachmentId,
                        NotifyId = entity.Id,
                        AttachmentType = NotifyConstants.通知类型.系统通知,
                    });
                }
                applicationContext.Transaction.Complete();//完成事务
            }
            catch (Exception ex)
            {
                applicationContext.Transaction.Abort();//回滚事务
                logger.LogError(ex, $"更新系统通知失败");
                throw new BusinessException("更新系统通知失败");
            }
        }

        /// <summary>
        /// 分页获取系统通知
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public IPagedList<SysNotify> GetSysNotifysByPage(NotifyQuery query, int pageIndex, int pageSize)
        {
            if (applicationContext?.CurrentUser?.Type == PmSoft.Entity.UserType.Corp)
                return repository.GetSysNotifysByPage(query, pageIndex, pageSize, 3);
            if (applicationContext?.CurrentUser?.Type == PmSoft.Entity.UserType.Constructor)
                return repository.GetSysNotifysByPage(query, pageIndex, pageSize, 2);
            if (applicationContext?.CurrentUser?.Type == PmSoft.Entity.UserType.Manager)
                return repository.GetSysNotifysByPage(query, pageIndex, pageSize, 4);
            if (applicationContext?.CurrentUser?.Type == PmSoft.Entity.UserType.Worker)
                return repository.GetSysNotifysByPage(query, pageIndex, pageSize, 5);
            return repository.GetSysNotifysByPage(query, pageIndex, pageSize, 0);
        }
    }
}